home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
EdRexx.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
14KB
|
476 lines
(****************************************************************************
:Program. EdRexx.mod
:Contents. Rexx- and Applications-Interface for AmokEd
:Author. Hartmut Goebel
:Language. Oberon
:Translator. AmigaOberon V2.00
:Imports. Printf (Volker Rudolph)
:History. V0.1, 3 Dec 1990, Hartmut Goebel
:History. V1.0, 14 Apr 1991 Hartmut Goebel [hG]
:History. V1.0b 19 Apr 1991 [hG] Portname enthält Adresse => eindeutig
:History. V1.1 20 Apr 1991 [hG] + Applications
:History. V1.1b 18 Jun 1991 [hG] Typedefs taken from Rexx.mod
:History. V1.2 16 Oct 1991 [hG] +GetVal, revised doRexx
:Date. 19 Oct 1991 03:44:06
****************************************************************************)
MODULE EdRexx;
IMPORT
Printf,
d : Dos,
e : Exec,
es : ExecSupport,
eAD: EdApplDefs,
edD: EdDisplay,
edE: EdErrors,
edG: EdGlobalVars,
edL: EdLowLevel,
lst: EdLists,
ol : OberonLib,
rx : Rexx, (* only Type Defs *)
str: Strings,
s : SYSTEM;
CONST
(*CallingARexxMacro = "Calling ARexx Macro ...";*)
UnknownCommand = "Unknown Command";
NoMacrosARexxNotActive = "Unknown Command -- No Macros: ARexx Not Active";
CreateRexxMsgFailed = "CreateRexxMsg() Failed";
FillRexxMsgFailed = "FillRexxMsg() Failed";
ApplicationNotFound = "Application not found";
(*RemoteError = "Remote error";*)
(*ARexxMacroExecHalted = "ARexx Macro Execution Halted";*)
ARexxMacroError = "ARexx Macro Error: Code = %ld Severity = %ld";
UserSpecifiedMacroError = "User Specified Macro Error: RC = %ld";
ApplAlreadyIncluded = "Application already included";
REXX = "REXX"; (* send to ARexx-Port "REXX" *)
CONST
(* Command *)
comm* = 1;
func* = 2;
close* = 3;
query* = 4;
addFH* = 7;
addLib* = 8;
remLib* = 9;
addCon* = 10;
remCon* = 11;
tcOpn* = 12;
tcCls* = 13;
(* ModifierFlags *)
noIO* = 0;
result* = 1;
moString* = 2;
token* = 3;
nonRet* = 4;
TYPE
ActionRec* = STRUCT
command* : SHORTINT;
modifier* : SHORTSET;
add* : INTEGER; (* eigentlich CARDINAL *)
END;
RexxMsgPtr* = POINTER TO RexxMsg;
RexxMsg * = STRUCT (node * : e.Message)
taskBlock * : e.APTR;
libBase * : e.LibraryPtr;
action* : ActionRec;
result1 * : LONGINT;
result2 * : LONGINT;
args * : ARRAY 16 OF e.STRPTR;
passPort * : e.MsgPortPtr;
commAddr * : e.STRPTR;
fileExt * : e.STRPTR;
stdin * : d.FileHandlePtr;
stdout * : d.FileHandlePtr;
avail * : LONGINT;
END;
VAR
rxs: e.LibraryPtr;
VAR
RxPort*: e.MsgPortPtr;
CmdMsg*: RexxMsgPtr; (* the incomming Msg *)
ApplArgCnt*: INTEGER;
RxPortSigBit*: LONGINT;
Buffer: edG.String;
ErrTitle: ARRAY 60 OF CHAR; (* für Fehlermeldungen *)
ApplList: lst.List;
TYPE
ApplPtr = POINTER TO Application;
Application = STRUCT (node: lst.Node)
name: edG.StringPtr;
port: edG.StringPtr;
END;
CONST
Extension = "aed";
(*------------------------------------------------------------------*)
(* $OvflChk- $RangeChk- $StackChk- $NilChk- $ReturnChk- $CaseChk- *)
PROCEDURE ClearRexxMsg{rxs,-156}(msgPtr{8}: RexxMsgPtr;
count{0}: LONGINT);
PROCEDURE CreateArgstring{rxs,-126}(string{8}: LONGINT;
length{0}: LONGINT): LONGINT;
PROCEDURE CreateRexxMsg{rxs,-144}(replyPort{8}: e.MsgPortPtr;
extension{9}: ARRAY OF CHAR;
host{0}: ARRAY OF CHAR): RexxMsgPtr;
PROCEDURE DeleteArgstring{rxs,-132}(argstring{8}: LONGINT);
PROCEDURE DeleteRexxMsg{rxs,-150}(packet{8}: RexxMsgPtr);
PROCEDURE FillRexxMsg{rxs,-162}(msgPtr{8}: RexxMsgPtr;
count{0}: LONGINT;
mask{1}: SET): BOOLEAN;
PROCEDURE FreePort{rxs,-234}(port{8}: e.MsgPortPtr);
PROCEDURE InitPort{rxs,-228}(port{8}: e.MsgPortPtr;
name{9}: ARRAY OF CHAR): LONGINT;
PROCEDURE IsRexxMsg*{rxs,-168}(msgPtr{8}: e.MessagePtr): BOOLEAN;
(* $OvflChk= $RangeChk= $StackChk- $NilChk= $ReturnChk= $CaseChk= *)
(*------------------------------------------------------------------*)
PROCEDURE IsApplMsg*(msg{8}: RexxMsgPtr): BOOLEAN;
BEGIN
IF msg.node.node.name = eAD.idAEd1 THEN
INCL(edG.Status,edG.isAppl); RETURN TRUE;
ELSIF msg.node.node.name = eAD.idAEd0 THEN
edG.Status := edG.Status - LONGSET{edG.isAppl} + LONGSET{edG.isRexx};
RETURN TRUE;
ELSE
edG.Status := edG.Status - LONGSET{edG.isAppl,edG.isRexx};
RETURN FALSE;
END;
END IsApplMsg;
PROCEDURE doRexx*(modifier: SHORTSET; port: edG.StringPtr; argo: e.ADDRESS);
VAR
RxMsg: RexxMsgPtr;
rxArg: rx.RexxArgPtr;
ARexxPort: e.MsgPortPtr;
oldTxt: edG.TextHeaderPtr;
oldlock: d.FileLockPtr;
cmd, buffer, aux: edG.StringPtr;
help: ARRAY 8 OF CHAR;
status: LONGSET;
argCnt: INTEGER;
BEGIN
IF NOT (edG.arexxAvail IN edG.Status) THEN
edL.Title(NoMacrosARexxNotActive); edG.Rc := edE.cmdFailed;
RETURN;
END;
RxMsg := CreateRexxMsg(RxPort,Extension,edG.AEdrxPort);
IF (RxMsg = NIL) AND (edG.Text # NIL) THEN
edL.Title(CreateRexxMsgFailed); edG.Rc := edE.cmdSevere;
RETURN;
END;
RxMsg.args[0] := argo;
(*
* from now on we use argo temporary
*)
RxMsg.args[eAD.TextSlot] := s.VAL(LONGINT,edG.Text);
IF argo = NIL THEN
RxMsg.action.command := close;
ELSE
IF NOT FillRexxMsg(RxMsg,1,{}) AND (edG.Text # NIL) THEN
(*
* wandelt gleich in Argstrings
*)
edL.Title(FillRexxMsgFailed); edG.Rc := edE.cmdSevere;
DeleteRexxMsg(RxMsg);
RETURN;
END;
RxMsg.action.command := comm;
END;
RxMsg.node.node.name := eAD.idAEd0;
RxMsg.action.modifier := modifier-SHORTSET{result};
oldTxt := NIL;
IF edG.Text # NIL THEN
oldlock := d.CurrentDir(edG.Text.dirLock);
EXCL(edG.Text.status,edG.keepTitle);
END;
e.Forbid;
ARexxPort := e.FindPort(port^);
IF ARexxPort # NIL THEN
e.PutMsg(ARexxPort,RxMsg);
e.Permit;
(*edL.Title(CallingARexxMacro);*)
LOOP
e.WaitPort(RxPort);
CmdMsg := e.GetMsg(RxPort);
IF RxMsg = CmdMsg THEN EXIT; END; (* eigene Msg zurück -> fertig *)
IF edG.Text # NIL THEN
IF IsRexxMsg(CmdMsg) OR IsApplMsg(CmdMsg) THEN
IF IsApplMsg(CmdMsg) AND (CmdMsg.args[eAD.TextSlot] # NIL)
AND (edG.Text # s.VAL(LONGINT,CmdMsg.args[eAD.TextSlot]))
AND lst.IsElement(edG.EditList,
s.VAL(LONGINT,CmdMsg.args[eAD.TextSlot]))
THEN
IF oldTxt=NIL THEN oldTxt := edG.Text END;
edD.SwitchEdit(s.VAL(LONGINT,CmdMsg.args[eAD.TextSlot]));
END;
EXCL(edG.Status,edG.cmdFound); (* neues Spiel, neues Glück *)
edG.Rc := edE.cmdInitial;
CmdMsg.result2 := edE.noError;
ApplArgCnt := 0;
COPY(CmdMsg.args[0]^,help); help[7] := 0X;
IF (result IN CmdMsg.action.modifier)
AND (edL.NCStrCmp(s.ADR(help),s.ADR("GETVAL ")) = 0) THEN
INCL(edG.Status,edG.cmdFound);
IF edG.isAppl IN edG.Status THEN
EXCL(edG.Status,edG.isAppl); (* so BreakOut works correctly *)
buffer := edL.CopyString(s.VAL(LONGINT,CmdMsg.args[1]));
ELSE
buffer := edL.CopyString(s.VAL(LONGINT,CmdMsg.args[0])+7);
END;
IF buffer # NIL THEN
argo := buffer;
cmd := edG.BreakOut(buffer,aux);
IF cmd # NIL THEN
CmdMsg.result2 := CreateArgstring(cmd,str.Length(cmd^)); END;
IF aux # NIL THEN DISPOSE(aux); END;
DISPOSE(argo);
END;
ELSE
argo := CmdMsg; (* sichern *)
status := edG.Status * LONGSET{edG.isAppl,edG.isRexx};
argCnt := ApplArgCnt;
edG.ExecCmd(s.VAL(LONGINT,CmdMsg.args[0]));
CmdMsg := argo; (* zurückschreiben *)
edG.Status := edG.Status + status; ApplArgCnt := argCnt;
END;
IF NOT (edG.cmdFound IN edG.Status) THEN
edG.Rc := edE.rxFailed;
CmdMsg.result2 := edE.cmdNotFound;
ELSIF edG.Rc < edE.FailLevel THEN
edG.Rc := edE.cmdValid0;
ELSE
CmdMsg.result2 := edG.ErrorCode;
END;
CmdMsg.result1 := edG.Rc;
END; (* IF IsRexxMsg OR IsApplMsg *)
END; (* edG.Text # NIL *)
e.ReplyMsg(CmdMsg);
END; (* LOOP *)
IF edG.Text # NIL THEN
IF oldTxt # NIL THEN edD.SwitchEdit(oldTxt); END;
INCL(edG.Status,edG.cmdFound);
IF edG.keepTitle IN edG.Text.status THEN
edG.Rc := edE.cmdValid2;
ELSIF (CmdMsg.result1 # 0) AND (edG.Rc = CmdMsg.result1) THEN
IF CmdMsg.result1 = 1 THEN
EXCL(edG.Status,edG.cmdFound);
edL.Title(UnknownCommand);
ELSE
Printf.SPrintf2(ErrTitle,ARexxMacroError,
CmdMsg.result2,CmdMsg.result1);
edL.Title(ErrTitle);
END;
ELSIF CmdMsg.result2 # 0 THEN
Printf.SPrintf1(ErrTitle,UserSpecifiedMacroError,CmdMsg.result2);
edL.Title(ErrTitle); edG.Rc := edE.cmdFailed;
END; (* IF CmdMsg.result1 # 0 *)
END; (* edG.Text # NIL *)
ELSE (* IF ARexxPort#NIL *)
e.Permit;
IF edG.Text # NIL THEN
edL.Title(NoMacrosARexxNotActive); END;
edG.Rc := edE.cmdError;
END;
IF edG.Text # NIL THEN
oldlock := d.CurrentDir(oldlock); END;
ClearRexxMsg(RxMsg,1);
DeleteRexxMsg(RxMsg);
edG.Status := edG.Status - LONGSET{edG.isAppl,edG.isRexx};
END doRexx;
PROCEDURE doRx*;
BEGIN
IF moString IN edG.ArgSet THEN
doRexx(SHORTSET{moString},s.ADR(REXX),edG.Arg[0]);
ELSE
doRexx(SHORTSET{},s.ADR(REXX),edG.Arg[0]);
END;
END doRx;
(*
* doRex1 is also used as implicit invocation interface between
* doCommand() and doRexx for ARexx macros implicitly called;
* arbitrary number of arguments
*)
PROCEDURE doRx1*;
BEGIN
Printf.SPrintf2(Buffer,"%s %s",edG.Arg[0],edG.Arg[1]);
doRexx(SHORTSET{},s.ADR(REXX),s.ADR(Buffer));
END doRx1;
PROCEDURE doRx2*;
BEGIN
Printf.SPrintf3(Buffer,"%s %s %s",edG.Arg[0],edG.Arg[1],edG.Arg[2]);
doRexx(SHORTSET{},s.ADR(REXX),s.ADR(Buffer));
END doRx2;
(* -------------------------------------------------------------------------*)
PROCEDURE FindApplNode(name: edG.StringPtr): ApplPtr;
VAR
appl: lst.NodePtr;
BEGIN
appl := ApplList.head;
WHILE appl # NIL DO
IF edL.NCStrCmp(appl(Application).name,name) = 0 THEN
RETURN appl(Application); END;
appl := appl.next;
END;
RETURN NIL;
END FindApplNode;
PROCEDURE GetApplPort*(find: edG.StringPtr): edG.StringPtr;
VAR
appl: ApplPtr;
BEGIN
appl := FindApplNode(find);
IF appl # NIL THEN RETURN appl.port ELSE RETURN NIL END;
END GetApplPort;
PROCEDURE ReleaseAppl(appl: ApplPtr);
BEGIN
lst.Remove(ApplList,appl);
(* DISPOSE(appl.port); DISPOSE(appl.name); *)
DISPOSE(appl); (* wurde ja am Stück alloziert!! *)
END ReleaseAppl;
PROCEDURE doApplAdd*;
VAR
appl: ApplPtr;
len0, len1: INTEGER;
BEGIN
IF FindApplNode(edG.Arg[0]) # NIL THEN
edL.Title(ApplAlreadyIncluded); edG.Rc := edE.cmdFailed;
RETURN;
END;
len0 := str.Length(edG.Arg[0]^)+1;
len1 := str.Length(edG.Arg[1]^)+1;
ol.New(appl,s.SIZE(Application)+len0+len1);
IF appl=NIL THEN
INCL(edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
RETURN;
END;
(* s.INIT(appl); STRUCT!! *)
appl.name := s.VAL(LONGINT,appl)+s.SIZE(Application);
appl.port := s.VAL(LONGINT,appl.name)+len0;
e.CopyMem(edG.Arg[0]^,appl.name^,len0);
e.CopyMem(edG.Arg[1]^,appl.port^,len1);
lst.AddTail(ApplList,appl);
Printf.SPrintf1(Buffer,"Appl installed: %s",edG.Arg[0]);
edL.Title(Buffer); edG.Rc := edE.cmdValid2;
END doApplAdd;
PROCEDURE doApplClose*;
VAR
appl: ApplPtr;
BEGIN
appl := FindApplNode(edG.Arg[0]);
IF appl#NIL THEN
doRexx(SHORTSET{},appl.port,NIL);
ReleaseAppl(appl);
END;
END doApplClose;
(*
* doAppl is also used as implicit invocation interface between
* doCommand() and doRexx for Applications implicitly called;
* arbitrary number of arguments
*)
PROCEDURE doAppl*;
VAR
appl: ApplPtr;
BEGIN
appl := FindApplNode(edG.Arg[0]);
IF appl#NIL THEN
doRexx(SHORTSET{},appl.port,edG.Arg[1]);
ELSE
edL.Title(ApplicationNotFound); edG.Rc := edE.cmdFailed;
END;
END doAppl;
(*--------------------------------------------------------------------------*)
PROCEDURE OpenRexx():BOOLEAN;
BEGIN
rxs := e.OpenLibrary(rx.rxsName,34);
IF rxs = NIL THEN RETURN FALSE; END;
(*
Printf.SPrintf1(edG.AEdrxPort,"AEd%08lx",e.FindTask(NIL));
RxPort := es.CreatePort(edG.AEdrxPort,0);
IF RxPort = NIL THEN RETURN FALSE; END;
*)
NEW(RxPort);
IF RxPort = NIL THEN RETURN FALSE; END;
Printf.SPrintf1(edG.AEdrxPort,"AEd%08lx",RxPort);
RxPortSigBit := InitPort(RxPort,edG.AEdrxPort);
IF RxPortSigBit = -1 THEN RETURN FALSE; END;
e.AddPort(RxPort);
INCL(edG.Status,edG.arexxAvail);
RETURN TRUE;
END OpenRexx;
PROCEDURE CloseRexx;
BEGIN
IF RxPort # NIL THEN
IF RxPortSigBit # -1 THEN
e.RemPort(RxPort); END;
(*
edL.DeletePort(RxPort);
*)
FreePort(RxPort);
DISPOSE(RxPort);
END;
edG.AEdrxPort := "";
IF rxs # NIL THEN e.CloseLibrary(rxs); END;
EXCL(edG.Status,edG.arexxAvail);
END CloseRexx;
BEGIN
lst.Init(ApplList);
IF NOT OpenRexx() THEN
CloseRexx; END;
CLOSE
WHILE ApplList.head # NIL DO
edG.Arg[0] := ApplList.head(Application).name;
doApplClose;
END;
CloseRexx;
END EdRexx.